#include "lab_4.h"
#include "laplace_blending.h"
#include "linear_blending.h"

#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>

void lab4()
{
  // Load images.
  // TODO: Load the images using cv::imread() and convert to 32-bit floating point images.
  // Using relative filenames such as "../tiger.png" should work.
  // Remember to rescale so that they have values in the interval [0, 1].
  // Hint: convertTo().
  cv::Mat img_1;
  img_1 = cv::imread("../white_tiger.png");
  img_1.convertTo(img_1, CV_32F, 1.0/255.0);
  showResult("Lab 4 - Image 1 original", img_1);

  cv::Mat img_2;
  img_2 = cv::imread("../tiger.png");
  img_2.convertTo(img_2, CV_32F, 1.0/255.0);
  showResult("Lab 4 - Image 2 original", img_2);

  // Construct weights.
  // TODO: Create a 32-bit, 3 channel floating point weight image.
  // The first half of the columns should be black (0.0f).
  // The last half of the coSlumns should be white (1.0f).
  // Then make a ramp between these two halves.
  // Hint: Use cv::blur() to make the ramp.

  // Create 1-channel float image: left half = 1.0, right half = 0.0
  cv::Mat base(img_1.size(), CV_32FC1, cv::Scalar(1.0f));
  int mid_col = base.cols / 2;
  base.colRange(mid_col, base.cols).setTo(0.0f);
  // Apply blur to create a smooth ramp
  const int ramp_width = 300;
  cv::blur(base, base, cv::Size(ramp_width * 2 + 1, 1));
  // Convert to 3 channels (RGB float)
  cv::Mat weights;
  cv::Mat channels[] = {base, base, base};
  cv::merge(channels, 3, weights);
 
  showResult("Lab 4 - Weights", weights);

  // Perform blending.
  // TODO: Finish linear_blending.cpp.
  cv::Mat lin_blend = linearBlending(img_1, img_2, weights);
  showResult("Lab 4 - Linear blend", lin_blend);

  // TODO: Finish laplace_blending.cpp.
  cv::Mat lap_blend = laplaceBlending(img_1, img_2, weights);
  showResult("Lab 4 - Laplace blend", lap_blend);

  // Show all results.
  // Press a key when finished.
  // If you close the windows, the program won't stop!
  cv::waitKey();
}

void showResult(const std::string& title, cv::Mat img)
{
  if (!img.empty())
  {
    cv::namedWindow(title, cv::WINDOW_NORMAL | cv::WINDOW_KEEPRATIO);
    cv::imshow(title, img);
  }
  else
  {
    std::cout << "\"" << title << "\" is not ready yet!\n";
  }
}
